﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;

namespace PowerTriggers
{
    public partial class frmMain : Form
    {
        private Program mainProgram;

        #region Form Events and Initialisation

        public frmMain(Program theMainProgram)
        {
            InitializeComponent();

            mainProgram = theMainProgram;

            //create an object of class Rectangle (rect)
            Rectangle rect = new Rectangle();

            //rect get data from the function returning the working area of the screen
            rect = Screen.GetWorkingArea(this);

            this.Left = (rect.Width - this.Width - 7);
            this.Top = (rect.Height - this.Height - 7);

            addTerminateMenuItem("Never", 0);
            addTerminateMenuItem("5 secs", 5);
            addTerminateMenuItem("10 secs", 10);
            addTerminateMenuItem("15 secs",15);
            addTerminateMenuItem("20 secs", 20);
            addTerminateMenuItem("25 secs", 25);
            addTerminateMenuItem("30 secs", 30);
            addTerminateMenuItem("40 secs", 40);
            addTerminateMenuItem("50 secs", 50);
            addTerminateMenuItem("1 min", 60);
            addTerminateMenuItem("1.5 mins", 90);
            addTerminateMenuItem("2 mins", 120);
            addTerminateMenuItem("5 mins", 360);
            addTerminateMenuItem("10 mins", 720);

            buildFormControls();

#if DEBUG
            cmdTest.Visible=true;
#endif
        }

        private void frmMain_Paint(object sender, PaintEventArgs e)
        {
            Pen myPen;
            Graphics formGraphics;

            // Draw a line after the summary section
            myPen = new Pen(SystemColors.ControlLight, 1);
            formGraphics = this.CreateGraphics();
            formGraphics.DrawLine(myPen, -3, 50, this.ClientSize.Width, 50);
            myPen.Dispose();
            formGraphics.Dispose();

            // Draw a line above the history panel
            myPen = new Pen(SystemColors.ControlLight, 1);
            formGraphics = this.CreateGraphics();
            formGraphics.DrawLine(myPen, -3, lstHistory.Top - 10, this.ClientSize.Width, lstHistory.Top - 10);
            myPen.Dispose();
            formGraphics.Dispose();
        }

        private void frmMain_Deactivate(object sender, EventArgs e)
        {
            if (mainProgram.gblnAutoHide == true) this.Close();
        }
        
        // Cancels the resize cursor
        protected override void WndProc(ref Message message)
        {
            const int WM_NCHITTEST = 0x0084;
            switch (message.Msg)
            {
                case WM_NCHITTEST:
                    return;
            }
            base.WndProc(ref message);
        }

        #endregion

        #region Control Events

        private void mnuPopup_Opening(object sender, CancelEventArgs e)
        {
            if (mnuPopup.SourceControl == cmdSuspend)
            {
                captureOutputToolStripMenuItem.Checked = Properties.Settings.Default.SuspendCapture;
                runMinimizedToolStripMenuItem.Checked = Properties.Settings.Default.SuspendRunMinimised;
                ChangeMethod(Properties.Settings.Default.SuspendMethod);
                ChangeTerminate(Properties.Settings.Default.SuspendTerminateAfterSec);
            }
            if (mnuPopup.SourceControl == cmdResume)
            {
                captureOutputToolStripMenuItem.Checked = Properties.Settings.Default.ResumeCapture;
                runMinimizedToolStripMenuItem.Checked = Properties.Settings.Default.ResumeRunMinimised;
                ChangeMethod(Properties.Settings.Default.ResumeMethod);
                ChangeTerminate(Properties.Settings.Default.ResumeTerminateAfterSec);
            }
        }

        private void addTerminateMenuItem(string DisplayName, int TotalSeconds)
        {
            ToolStripMenuItem mnu = new System.Windows.Forms.ToolStripMenuItem();

            mnu.Name = "Terminate";
            mnu.Tag = TotalSeconds;
            mnu.Text = DisplayName;
            mnu.Click += new EventHandler(TerminateMenuClick);
            terminateAfterSecsToolStripMenuItem.DropDownItems.Add(mnu);
        }

        void TerminateMenuClick(object sender, EventArgs e)
        {
            ChangeTerminate(((int)((ToolStripMenuItem)sender).Tag));
        }

        private void method1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeMethod(1);
        }

        private void method2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeMethod(2);
        }

        private void method3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeMethod(3);
        }

        private void ChangeMethod(int NewMethod)
        {
            switch (NewMethod)
            {
                case 1:
                    method1ToolStripMenuItem.Checked = true;
                    method2ToolStripMenuItem.Checked = false;
                    method3ToolStripMenuItem.Checked = false;
                    runMinimizedToolStripMenuItem.Checked = false;
                    runMinimizedToolStripMenuItem.Visible = false;
                    captureOutputToolStripMenuItem.Visible = true;
                    terminateAfterSecsToolStripMenuItem.Visible = false;
                    break;
                case 2:
                    method1ToolStripMenuItem.Checked = false;
                    method2ToolStripMenuItem.Checked = true;
                    method3ToolStripMenuItem.Checked = false;
                    runMinimizedToolStripMenuItem.Checked = false;
                    runMinimizedToolStripMenuItem.Visible = false;
                    captureOutputToolStripMenuItem.Checked = false;
                    captureOutputToolStripMenuItem.Visible = false;
                    terminateAfterSecsToolStripMenuItem.Visible = true;
                    break;
                case 3:
                    method1ToolStripMenuItem.Checked = false;
                    method2ToolStripMenuItem.Checked = false;
                    method3ToolStripMenuItem.Checked = true;
                    runMinimizedToolStripMenuItem.Visible = true;
                    captureOutputToolStripMenuItem.Checked = false;
                    captureOutputToolStripMenuItem.Visible = false;
                    terminateAfterSecsToolStripMenuItem.Visible = true;
                    break;
            }

            if (((string)mnuPopup.Tag) == "Suspend")
            {
                Properties.Settings.Default.SuspendMethod = NewMethod;
                Properties.Settings.Default.SuspendRunMinimised = runMinimizedToolStripMenuItem.Checked;
                Properties.Settings.Default.SuspendCapture = captureOutputToolStripMenuItem.Checked;
            }
            if (((string)mnuPopup.Tag) == "Resume")
            {
                Properties.Settings.Default.ResumeMethod = NewMethod;
                Properties.Settings.Default.ResumeRunMinimised = runMinimizedToolStripMenuItem.Checked;
                Properties.Settings.Default.ResumeCapture = captureOutputToolStripMenuItem.Checked;
            }

            Properties.Settings.Default.Save();
        }

        private void ChangeTerminate(int TerminateSeconds)
        {
            foreach (ToolStripMenuItem mnu in terminateAfterSecsToolStripMenuItem.DropDownItems)
            {
                mnu.Checked = (((int)mnu.Tag) == TerminateSeconds);
            }

            if (((string)mnuPopup.Tag) == "Suspend")
                Properties.Settings.Default.SuspendTerminateAfterSec = TerminateSeconds;
            
            if (((string)mnuPopup.Tag) == "Resume")
                Properties.Settings.Default.ResumeTerminateAfterSec = TerminateSeconds;

            Properties.Settings.Default.Save();
        }

        private void selectFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mainProgram.gblnAutoHide = false;
            
            if (mnuPopup.SourceControl == cmdSuspend)
            {
                openFile.FileName = Properties.Settings.Default.SuspendAction;
                if (openFile.ShowDialog(this) == DialogResult.OK)
                {
                    Properties.Settings.Default.SuspendAction = openFile.FileName;
                    Properties.Settings.Default.Save();
                    buildFormControls();
                }
            }

            if (mnuPopup.SourceControl == cmdResume)
            {
                openFile.FileName = Properties.Settings.Default.ResumeAction;
                if (openFile.ShowDialog(this) == DialogResult.OK)
                {
                    Properties.Settings.Default.ResumeAction = openFile.FileName;
                    Properties.Settings.Default.Save();
                    buildFormControls();
                }
            }

            mainProgram.gblnAutoHide = true;
        }

        private void clearFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mainProgram.gblnAutoHide = false;

            if (mnuPopup.SourceControl == cmdSuspend) Properties.Settings.Default.SuspendAction = "";
            if (mnuPopup.SourceControl == cmdResume) Properties.Settings.Default.ResumeAction = "";

            Properties.Settings.Default.Save();
            buildFormControls();

            mainProgram.gblnAutoHide = true;
        }

        private void captureOutputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mainProgram.gblnAutoHide = false;

            if (mnuPopup.SourceControl == cmdSuspend)
                Properties.Settings.Default.SuspendCapture = !Properties.Settings.Default.SuspendCapture;
            
            if (mnuPopup.SourceControl == cmdResume)
                Properties.Settings.Default.ResumeCapture = !Properties.Settings.Default.ResumeCapture;

            Properties.Settings.Default.Save();
            buildFormControls();

            mainProgram.gblnAutoHide = true;
        }

        private void runMinimizedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (mnuPopup.SourceControl == cmdSuspend)
                Properties.Settings.Default.SuspendRunMinimised = !Properties.Settings.Default.SuspendRunMinimised;

            if (mnuPopup.SourceControl == cmdResume)
                Properties.Settings.Default.ResumeRunMinimised = !Properties.Settings.Default.ResumeRunMinimised;

            Properties.Settings.Default.Save();
        }

        private void cmdSuspend_Click(object sender, EventArgs e)
        {
            mnuPopup.Tag = "Suspend";
            cmdSuspend.ContextMenuStrip.Show(cmdSuspend, new Point(cmdSuspend.Width, cmdSuspend.Height), ToolStripDropDownDirection.BelowLeft);
        }

        private void cmdResume_Click(object sender, EventArgs e)
        {
            mnuPopup.Tag = "Resume";
            cmdResume.ContextMenuStrip.Show(cmdResume, new Point(cmdResume.Width, cmdResume.Height), ToolStripDropDownDirection.BelowLeft);
        }

        private void cmdTest_Click(object sender, EventArgs e)
        {
            string strPath;
            string strFile;

            if (Properties.Settings.Default.ResumeAction != null)
            {
                strPath = Properties.Settings.Default.ResumeAction;
                strFile = Path.GetFileName(strPath);
                strPath = Path.GetDirectoryName(strPath);

                mainProgram.AddHistory("TEST: Running action (" + strFile + ")");
                buildFormControls();
                lstHistory.Refresh();

                try
                {
                    string output = "";

                    Process runCommand = new Process();
                    runCommand.StartInfo.FileName = Properties.Settings.Default.ResumeAction;
                    //runCommand.StartInfo.FileName = "cmd.exe";
                    //runCommand.StartInfo.Arguments = String.Format("/c \"{0}\"", Properties.Settings.Default.ResumeAction);
                    runCommand.StartInfo.WorkingDirectory = strPath;
                    runCommand.StartInfo.UseShellExecute = false;
                    runCommand.StartInfo.RedirectStandardOutput = Properties.Settings.Default.ResumeCapture;
                    runCommand.Start();
                    if (Properties.Settings.Default.ResumeCapture)
                        output = runCommand.StandardOutput.ReadToEnd();
                    
                    runCommand.WaitForExit();

                    //TODO:DS WaitForExit is waiting for all spawned processes also.

                    mainProgram.AddHistory("TEST: Action complete");
                    if (Properties.Settings.Default.ResumeCapture) mainProgram.AddHistory(output);
                    buildFormControls();
                    lstHistory.Refresh();
                }
                catch (Exception ex)
                {
                    mainProgram.AddHistory("TEST: " + ex.Message);
                }
            }
        }

        private void lstHistory_DoubleClick(object sender, EventArgs e)
        {
            mainProgram.gblnAutoHide = false;
            MessageBox.Show(lstHistory.SelectedItem.ToString(), "Power Triggers", MessageBoxButtons.OK, MessageBoxIcon.Information);
            mainProgram.gblnAutoHide = true;
        }

        #endregion
        
        #region Form Layout Methods

        private void buildFormControls()
        {
            txtSuspend.Text = CompactPath(Properties.Settings.Default.SuspendAction, 44);
            txtResume.Text = CompactPath(Properties.Settings.Default.ResumeAction, 44);

            lstHistory.Items.Clear();
            for (int i = Properties.Settings.Default.History.Count-1; i >= 0; i--)
            {
                lstHistory.Items.Add(Properties.Settings.Default.History[i]);
            }
        }

        #endregion

        [DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
        static extern bool PathCompactPathEx([Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);

        public static string CompactPath(string longPathName, int wantedLength)
        {
            // NOTE: You need to create the builder with the required capacity before calling function.
            // See http://msdn.microsoft.com/en-us/library/aa446536.aspx
            StringBuilder sb = new StringBuilder(wantedLength + 1);
            PathCompactPathEx(sb, longPathName, wantedLength + 1, 0);
            return sb.ToString();
        }
    }
}
